PowerShell 7.4の試験的な機能 Feedback Providers について
しばたです。
少し前にPowerShell Team Blogで新しい試験的な機能として「Feedback Providers」を増やした旨のアナウンスがありました。
ちょっと面白い機能だったので本記事で解説したいと思います。
Feedback Providers とは
Feedback ProvidersはユーザーがPowerShellプロンプト上で対話的にコマンドを実行した際の結果(成功、失敗、コマンドが見つからない、等)に応じて独自の応答メッセージ(フィードバック)を追加できる機能になります。
他シェルにあるpostexec
に近い雰囲気ですが、PowerShellではあくまでもフィードバックを返すだけであり自由に処理をフックできない点が異なります。
以前からPSCommandNotFoundSuggestion
というコマンド名を間違えて入力した際に正しいと推測される名称をサジェストしてくれる試験的な機能があるのですが、これを実装した際に「より汎用的な仕組みを用意した方が良い」という判断になりFeedback Providerが生まれた様です。
Feedback Providersの仕様
具体的な仕様は以下のRFCで提案されています。
フィードバックの書式
本日時点でフィードバックの書式は以下の様に提案されています。
[Providerの名前]
ヘッダー (required):
➤ アクション1 (optional)
➤ アクション2 (optional)
➤ アクションn (optional)
フッター (optional)
# 複数Providerがある場合は上記を繰り返す
Provider作成者が自由にレイアウトを決めるわけではなく、一定の書式に従う形になっています。
「ヘッダー」欄はシンプルに長文テキストを記述する自由欄として使われるケースも想定している様です。
フィードバックのトリガー
フィードバックを発生させるトリガーは5つ提案されています。
- Comments
- Success
- CommandNotFound
- Error
- All
Comments トリガー
いきなり変わったトリガーが出てきましたが、これはプロンプトにコメント文(#
で始まる文)を入力した際に発火するトリガーです。
PowerShellの利用において通常この様な行為しませんし、仮に実行しても何もせず終了するだけです。
RFCに記載されている意図としてはGitHub Copilotの様なコメントを読んで応答してくれるAI(を実装したProvider)での利用を想定しています。
PS># How do I list the files in my C drive?
[A.I Model]
One way to list all your files in the C drive is the following:
➤ Get-ChildItem -Path C:
(RFCの例を転記 : コメントを書くとAIを実装したProviderがいい感じにフィードバックしてくれる)
Success トリガー
Successはコマンドが正常終了した時に発火するトリガーです。
RFCでは実行したコマンドに対し「より良い方法があればそれを提案する」といった使い方を想定しています。
CommandNotFound トリガー
CommandNotFoundは実行しようとしたコマンドが見つからなかった場合に発火するトリガーです。
そして現時点でデフォルトのトリガーでもあります。
前述の通り「適切なコマンドをサジェストする」使い方を想定しています。
Error トリガー
Errorはコマンドが異常終了した時に発火するトリガーです。
厳密にはCommandNotFound
もエラーの一種ですが、トリガーとしてはCommandNotFound
とそれ以外で区別されます。
PowerShell側では全てのエラーがトリガー対象となり、フィードバックを返すべきエラーを選択するのはProvider作成者の責務となっています。
All トリガー
Allは名前通り前述のすべてのタイミングでトリガーを発火させる設定です。
実行順など
複数のProviderを利用する際はImport-Module
を明示的に実行して、インポートされた順にフィードバックを返す仕様になっています。
# インポート順でフィードバックを返す
Import-Module FeedbackProvider1
Import-Module FeedbackProvider2
PS>something to trigger feedback providers
[FeedbackProvider1]
Header 1:
➤ Action
[FeedbackProvider2]
Header2:
➤ Action
また、フィードバックから直接的に後続の処理を実行することは出来ないものの、予測変換のPredictorと間接的に連携させることは想定している様です。
- 参考 : command-not-found feedback provider
試してみた
ここからは実際に試していきます。
私の開発用PC(Windows 11)にインストールしたPowerShell 7.4-Preview.4を動作確認に使っていきます。
PowerShellのインストール方法は割愛します。
C:\> $PSVersionTable.PSVersion
Major Minor Patch PreReleaseLabel BuildLabel
----- ----- ----- --------------- ----------
7 4 0 preview.4
試験的な機能の有効化
Feedback ProvidersはPSFeedbackProvider
と言う名前の試験的な機能で提供されています。
C:\> Get-ExperimentalFeature -Name PSFeedbackProvider | Format-List
Name : PSFeedbackProvider
Enabled : False
Source : PSEngine
Description : Replace the hard-coded suggestion framework with the extensible feedback provider
Enable-ExperimentalFeature
コマンドでこの機能を有効にしてPowerShellコンソールを再起動します。
併せてPSCommandNotFoundSuggestion
機能も有効にしてやります。
# Feedback Providersの機能を有効に
C:\> Enable-ExperimentalFeature -Name PSFeedbackProvider
WARNING: Enabling and disabling experimental features do not take effect until next start of PowerShell.
# PSCommandNotFoundSuggestion はFeedback Providerとして再実装されている
C:\> Enable-ExperimentalFeature -Name PSCommandNotFoundSuggestion
WARNING: Enabling and disabling experimental features do not take effect until next start of PowerShell.
再起動後これらの試験的な機能が有効になっていればOKです。
C:\> Get-ExperimentalFeature -Name PSFeedbackProvider, PSCommandNotFoundSuggestion | Select-Object Name, Enabled
Name Enabled
---- -------
PSCommandNotFoundSuggestion True
PSFeedbackProvider True
動作確認
この状態で適当にコマンドを打ち間違えてみると、「コマンドが無い」エラーの後にFeedback Providerによるサジェストが表示される様になりました。
(dirr
とdir
コマンドを打ち間違えてみる)
[general]
The most similar commands are:
> dir
PSCommandNotFoundSuggestion
の試験的な機能自体は以前からあったため、既にお使いの方からするとわかりにくいかもしれませんが、サジェストの書式がRFCに沿ったものに変わっている点からFeedback Providerを使う様になったことが見て取れます。
補足 : JSON Adapter Feedback Provider を試してみる
PowerShell Team Blogでは別の例としてJSON Adapter Feedback ProviderというProviderを紹介しています。
補足としてこいつも動作確認しておきます。
JSON Adapter Feedback Providerはネイティブコマンド向けのProviderで、あるコマンドを実行した際にPATH上に"コマンド名"-json.ps1
というスクリプトファイルがある場合に「コマンド | コマンド名-json
の形式でも実行可能だよ。」とお知らせしてくれるものになります。
"コマンド名"-json.ps1
自体は自分で作り込む必要があり、ネイティブコマンドの結果をパースしてJSONにする処理を書いてやります。
要はPowerShell Crescendoと同様の目的を別のアプローチで試みている感じですね。
PowerShell Teamとしては有志で"コマンド名"-json.ps1
を作り公開し共有する想定なんだと思いますが、現時点では全部自分で作り込む必要があるので正直しんどいです...
一応この他にjcコマンドとの連携機能もあり、jcがインストールされた環境でjcと連携可能なコマンドが実行された場合にもフィードバックを返してくれます。
こちらの機能は試しやすいので、本記事ではAWS CloudShell(Amazon Linux 2環境)にPowerShell 7.4-preview.4とjcをインストールした環境で動作確認していきます。
はじめにAWS CloudShellを起動し、以下のコマンドを実行して両者をインストールしておきます。
# AWS CloudShellにPowerShell 7.4-preview.4とjcをインストール
sudo yum install -y https://github.com/PowerShell/PowerShell/releases/download/v7.4.0-preview.4/powershell-preview-7.4.0_preview.4-1.rh.x86_64.rpm
sudo yum install -y https://github.com/kellyjonbrazil/jc/releases/download/v1.23.3/jc-1.23.3-1.x86_64.rpm
続けてpwsh-preview
コマンドを実行してPowerShellを起動したうえでMicrosoft.PowerShell.JsonAdapter
モジュールをインストールして明示的にインポートしておきます。
# モジュールのインストール
Install-Module -Name Microsoft.PowerShell.JsonAdapter -AllowPrerelease -Force
# 明示的にインポートしてProviderを使用する
Import-Module Microsoft.PowerShell.JsonAdapter
LinuxのPowerShell Preview版はデフォルトで全ての試験的な機能が有効になっているためこれで準備完了です。
jcで対応しているuname -a
コマンドを実行してみると以下の様な感じでProviderがuname -a | jc --uname | ConvertFrom-Json
の利用を薦めてくれます。
加えて入力補完にも表示される様になります。
[JsonAdapter]
Json adapter found additional ways to run.
➤ uname -a | jc --uname | ConvertFrom-Json
フィードバックに従いuname -a | jc --uname | ConvertFrom-Json
を実行するとこんな感じでよりPowerShellらしい操作になりました。
一応uname -a | jc --uname
の結果も記載しておきます。
最後に
以上となります。
シンプルな仕組みですが面白いですね。
これから登場するProviderによっては非常に便利な体験を得ることができそうですし、できるだけ早く正式な機能になって欲しいと思った次第です。